package com.nxj.factory;

import com.nxj.annotations.MyRequestMapping;
import com.nxj.annotations.MySecurity;
import com.nxj.pojo.Handler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

public class HandlerMappingGenerator {

    private static List<Handler> handlers = new ArrayList<>();

    public static void doMappring() {
        System.out.println("开始初始化 mvc-mapper...");
        for (Map.Entry<String, Object> entry : IOCFactory.objects.entrySet()) {
            if (entry.getValue().getClass().isAnnotationPresent(MyRequestMapping.class)) {
                String baseUrl = (entry.getValue().getClass().getAnnotation(MyRequestMapping.class)).value();
                for (Method method : entry.getValue().getClass().getMethods()) {
                    if (method.getAnnotation(MyRequestMapping.class) == null) continue;
                    String methodUrl = method.getAnnotation(MyRequestMapping.class).value();
                    Handler handler = new Handler();
                    handler.setController(entry.getValue());
                    handler.setMethod(method);
                    handler.setPattern(Pattern.compile(baseUrl + "" + methodUrl));

                    Map<String, Integer> paramIndexMap = new HashMap<>();
                    int i = 0;
                    for (Parameter parameter : method.getParameters()) {
                        if (parameter.getType() == HttpServletRequest.class || parameter.getType() == HttpServletResponse.class)
                            paramIndexMap.put(parameter.getType().getSimpleName(), i);
                        else paramIndexMap.put(parameter.getName(), i);
                        i++;
                    }
                    handler.setParamIndexMap(paramIndexMap);

                    if (method.getAnnotation(MySecurity.class) != null)
                        handler.setSecuritys(method.getAnnotation(MySecurity.class).value());

                    System.out.println(handler);
                    addMapper(handler);
                }
            }
        }
    }

    public static void addMapper(Handler handler) {
        handlers.add(handler);
    }

    public static Handler mapHandler(String mapperKey) {
        for (Handler handler : handlers) if (handler.getPattern().matcher(mapperKey).matches()) return handler;

        return null;
    }

}
